tkinter绘制组件(12)

您所在的位置:网站首页 tkinter 表格 选择框 tkinter绘制组件(12)

tkinter绘制组件(12)

2024-07-14 01:20| 来源: 网络整理| 查看: 265

tkinter绘制组件(12)——表格 引言构思外观绘制方法 布局函数结构绘制表头绘制表格内容获取高度和重绘完整代码函数 效果测试代码最终效果2021-12-12新样式2022-1-2新样式2022-7-3新功能2024-1-26新样式 补充说明github项目pip下载结语

引言

在GUI中,表格作为一种数据呈现的方式组件,会运用到数据反馈等功能中,让用户对程序处理的结果有一种较为直观的感受。因此,绘制表格也是TinUI走向成熟一个重要里程。

实际上,我对tkinter(tcl\tk)自身的表格(Treeview)很不满。首先,列宽虽然能够自定义,但不能够自动适配表头内容,默认情况下,表头宽度是一定的。其次,单元格的内容不能够换行,否则无法显示除了第一行以外的其它内容,而且如果第一行的文本超过了列宽,它居然就不显示了,还得用户自己调整表格宽度。以上的这些缺点,对任何人都不太友好,那么TinUI绘制表格的主要目标就是表格尺寸与内容自动契合。

再次剧透 ,TinUI绘制的表格(又)是目前最复杂的组件绘制。

构思

TinUI的表格究竟如何绘制,还是考虑了一段时间的。

外观

想想那个UWP并没有原生表格控件,其中的表格都是由DataGrid等单元格组件绘制出来的。因此,TinUI也将以单元格的应试绘制表格单元。TinUI的表格也不会支持宽度手动改变,目前也没想要明显区分表头和表格内容。

看起来TinUI绘制表格简化了很多工作,但是我们的最终目的——绘制一个自动契合内容的表格,是必须要达成的。

绘制方法

为了契合表格内容,绘制过程中需要用到大量的计算和平面图形想象。

绘制基本流程如下:

从表头组中获取第n表头内容 绘制表头文本 绘制表头单元格 确定第n列列宽 获取第a行内容组 a>1 获取第b列内容 绘制第b列文本内容 绘制单元格 将单元格高度加入a行高度组 获取第a行单元格最大高度 重绘a行单元格 完成绘制

有了逻辑图,接下来就可以开工了。

布局 函数结构 def add_table(self,pos:tuple,outline='#E1E1E1',fg='black',bg='white',data=[['1','2','3'],['a','b','c']],minwidth=100,font=('微软雅黑',12)):#绘制表格 ''' pos::位置 outline::边框颜色 fg::文本颜色 bg::单元格颜色 data::表格数据。格式:((title,...,...),(content,...,...),...) minwidth::最小列宽 font::字体 ''' 绘制表头

根据逻辑图,绘制表头时,先绘制表头文本,再绘制单元格,同时,将列宽记录到宽度组。

为了方便后面获取特定列的列宽,宽度组的设计如下:

line_width={1:width1,2:width2,3:width3,...}

绘制代码如下:

title_num=len(data[0])#获取表头个数 end_x,end_y=pos#起始位置 height=0 line_width={}#获取每列的固定宽度 count=1#列数 for i in data[0]:#绘制表头 title=self.create_text((end_x,end_y),anchor='nw',text=i,fill=fg,font=font) bbox=self.bbox(title) #判断最小宽度 if bbox[2]-bbox[0]height else height #重新绘制 for back in widths.keys(): self.delete(widths[back][0]) x1,y1,x2=widths[back][2] y2=y1+height newback=self.create_rectangle((x1,y1,x2,y2),outline=outline,fill=bg) self.lower(newback) return height end_y=pos[1]+height+2 for line in data[1:]: #... for a in line: #... height=get_max_height(a_dict) end_y=end_y+height+2

经过以上的一波操作,一个能够自定义颜色、适配列宽、自动调整单元格高度以显示全部内容的表格组件已经被绘制出来了。

完整代码函数 def add_table(self,pos:tuple,outline='#E1E1E1',fg='black',bg='white',data=[['1','2','3'],['a','b','c']],minwidth=100,font=('微软雅黑',12)):#绘制表格 def get_max_height(widths:dict): height=0 for i in widths.values(): height=i[1] if i[1]>height else height #重新绘制 for back in widths.keys(): self.delete(widths[back][0]) x1,y1,x2=widths[back][2] y2=y1+height newback=self.create_rectangle((x1,y1,x2,y2),outline=outline,fill=bg) self.lower(newback) return height title_num=len(data[0])#获取表头个数 end_x,end_y=pos#起始位置 height=0 line_width={}#获取每列的固定宽度 count=1 for i in data[0]: title=self.create_text((end_x,end_y),anchor='nw',text=i,fill=fg,font=font) bbox=self.bbox(title) if bbox[2]-bbox[0]


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3